x86 hvm: Do not incorrectly retire an instruction emulation when a
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 7 Oct 2009 06:21:31 +0000 (07:21 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 7 Oct 2009 06:21:31 +0000 (07:21 +0100)
read/write cycle to qemu is dropped due to guest suspend.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/emulate.c
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/io.c
xen/include/asm-x86/hvm/hvm.h

index a8c6d1a5e326f179dce42aef8da65d1a54135693..ac3f807c22f964ead48517689de8130233361c66 100644 (file)
@@ -163,8 +163,8 @@ static int hvmemul_do_io(
         curr->arch.hvm_vcpu.io_state = HVMIO_none;
         break;
     case X86EMUL_UNHANDLEABLE:
-        hvm_send_assist_req(curr);
-        rc = (p_data != NULL) ? X86EMUL_RETRY : X86EMUL_OKAY;
+        rc = (!hvm_send_assist_req(curr) || (p_data != NULL)
+              ? X86EMUL_RETRY : X86EMUL_OKAY);
         break;
     default:
         BUG();
index 8d96b30ceed5fa70aca21707905f639c670237a4..a89b616c489fc168f4fb1e111ff4be3623f52b99 100644 (file)
@@ -858,12 +858,12 @@ void hvm_vcpu_down(struct vcpu *v)
     }
 }
 
-void hvm_send_assist_req(struct vcpu *v)
+bool_t hvm_send_assist_req(struct vcpu *v)
 {
     ioreq_t *p;
 
     if ( unlikely(!vcpu_start_shutdown_deferral(v)) )
-        return; /* implicitly bins the i/o operation */
+        return 0; /* implicitly bins the i/o operation */
 
     p = &get_ioreq(v)->vp_ioreq;
     if ( unlikely(p->state != STATE_IOREQ_NONE) )
@@ -871,7 +871,7 @@ void hvm_send_assist_req(struct vcpu *v)
         /* This indicates a bug in the device model. Crash the domain. */
         gdprintk(XENLOG_ERR, "Device model set bad IO state %d.\n", p->state);
         domain_crash(v->domain);
-        return;
+        return 0;
     }
 
     prepare_wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port);
@@ -882,6 +882,8 @@ void hvm_send_assist_req(struct vcpu *v)
      */
     p->state = STATE_IOREQ_READY;
     notify_via_xen_event_channel(v->arch.hvm_vcpu.xen_port);
+
+    return 1;
 }
 
 void hvm_hlt(unsigned long rflags)
index 42a7b63b9803c70382b375c14a4558b810fc6616..f49626ea5f133ff325a941e92dc7ec2b958d328e 100644 (file)
@@ -168,7 +168,7 @@ void send_invalidate_req(void)
     p->data = ~0UL; /* flush all */
     p->io_count++;
 
-    hvm_send_assist_req(v);
+    (void)hvm_send_assist_req(v);
 }
 
 int handle_mmio(void)
index 563e2119293fd89373f0ccb9b692f1e50e7d214f..2ee9b81a06dff12e26b67bd6c7d25ea5655542d8 100644 (file)
@@ -148,7 +148,7 @@ int hvm_vcpu_cacheattr_init(struct vcpu *v);
 void hvm_vcpu_cacheattr_destroy(struct vcpu *v);
 void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip);
 
-void hvm_send_assist_req(struct vcpu *v);
+bool_t hvm_send_assist_req(struct vcpu *v);
 
 void hvm_set_guest_tsc(struct vcpu *v, u64 guest_tsc);
 u64 hvm_get_guest_tsc(struct vcpu *v);